/*
*	(*^。^*) TFrameWork License (*^。^*)
*/

/*
 *  Title :  
 *          
 *  Description :  
 *          
 *          
 *  Date : 
 *
 *  Author : DengPing
 *
 *  Modify : 
 */
using UnityEngine;
using UnityEngine.UIElements;

namespace TFrameWork.Module.ActionEditor
{
    public class AnimationTrack : TrackBase
    {
        protected override string trackName => "动画轨道";
        protected override TrackStyleBase _trackStyle { get; set; }

        /// <summary>
        /// 信号轨道数据
        /// </summary>
        public TrackData trackData => ActionEditor.Instance.ActionData.GetTrackList<AnimationEvent>();

        /// <summary>
        /// 检查是否可以删除子轨道
        /// </summary>
        /// <returns></returns>
        private bool CheckDeleteChildTrack(int index)
        {
            return true;
        }

        /// <summary>
        /// 检查添是否可以加子轨道
        /// </summary>
        /// <returns></returns>
        private bool CheckAddChildTrack()
        {
            return true;
        }

        public override void ResetLoadTrack()
        {
            // 销毁当前已有
            Destroy();

            // 根据数据绘制轨道UI样式
            var animationTrackStyle = new AnimationTrackStyle();
            _trackStyle = animationTrackStyle;
            animationTrackStyle.Init(menuParent, trackParent, this, trackData, trackName, CheckAddChildTrack,
                CheckDeleteChildTrack);
        }

        public Vector3 GetPositionForRootMotion(int frameIndex, bool recove = false)
        {
            Vector3 rootMotionPos = Vector3.zero;
            GameObject previewGameObject = ActionEditor.Instance.PreviewCharacterObj;
            Animator animator = previewGameObject.GetComponent<Animator>();
            // 根据帧找到目前是哪个动画
            var framData = trackData.trackDatas;
            for (int i = 0; i < framData.Count; i++)
            {
                var trackItem = framData[i];
                if (!trackItem.IsDisable)
                {
                    #region 根运动计算

                    int[] frameIndexKeys = new int[trackItem.events.Count];
                    for (int j = 0; j < trackItem.events.Count; j++)
                    {
                        frameIndexKeys[j] = trackItem.events[j].startIndex;
                    }

                    for (int j = 0; j < trackItem.events.Count; j++)
                    {
                        int key = frameIndexKeys[j]; //当前动画的起始帧
                        AnimationEvent animationEvent = trackItem.events[j] as AnimationEvent;
                        if (animationEvent.applyRootMotion == false)
                        {
                            UpdatePosture(frameIndex);
                            continue;
                        }

                        //下一个动画帧
                        int nextIndexFrame = 0;
                        if (j + 1 < frameIndexKeys.Length) nextIndexFrame = frameIndexKeys[j + 1];
                        else nextIndexFrame = ActionEditor.Instance.ActionData.FrameCount;

                        bool isBrack = false; //标记是最后一次采样
                        if (nextIndexFrame > frameIndex)
                        {
                            nextIndexFrame = frameIndex;
                            isBrack = true;
                        }

                        //持续的帧数 = 下一个动画的帧数 - 这个动画的开始时间
                        int durationFrameCount = nextIndexFrame - key;
                        if (durationFrameCount > 0)
                        {
                            //动画资源的总帧数
                            float clipFrameCount = animationEvent.animationClip.length *
                                                   ActionEditor.Instance.ActionData.FrameRote;
                            //当前的播放进度
                            float totalProgress = durationFrameCount / clipFrameCount;
                            //播放次数
                            int playTimes = 0;
                            //最终不完美的一次播放进度
                            float lastProgress = 0;
                            //只有循环动画才需要采样多次
                            if (animationEvent.animationClip.isLooping)
                            {
                                playTimes = (int)totalProgress;
                                lastProgress = totalProgress - playTimes;
                            }
                            else
                            {
                                //不循环的动画 如果进度超过1 约束成1 
                                if (totalProgress >= 1f)
                                {
                                    playTimes = 1;
                                    lastProgress = 0;
                                }
                                else if (totalProgress < 1f)
                                {
                                    lastProgress = totalProgress; //总进度小于1 本身就是最后一次播放
                                    playTimes = 0;
                                }
                            }

                            //采样计算
                            animator.applyRootMotion = true;
                            if (playTimes >= 1)
                            {
                                //采样一次动画的完整进度
                                animationEvent.animationClip.SampleAnimation(previewGameObject,
                                    animationEvent.animationClip.length);
                                //采样结果
                                Vector3 samplePos = previewGameObject.transform.position;
                                rootMotionPos += samplePos * playTimes;
                            }

                            if (lastProgress > 0)
                            {
                                //采样一次动画的不完整进度
                                animationEvent.animationClip.SampleAnimation(previewGameObject,
                                    animationEvent.animationClip.length * lastProgress);
                                //采样结果
                                Vector3 samplePos = previewGameObject.transform.position;
                                rootMotionPos += samplePos;
                            }
                        }

                        if (isBrack) break;
                    }
                }
            }

            if (recove)
            {
                UpdatePosture(ActionEditor.Instance.CurrentSelectFrameIndex);
            }

            return rootMotionPos;
        }

        private void UpdatePosture(int frameIndex)
        {
            GameObject previewGameObject = ActionEditor.Instance.PreviewCharacterObj;
            Animator animator = previewGameObject.GetComponent<Animator>();
            // 根据帧找到目前是哪个动画
            var framData = trackData.trackDatas;
            for (int i = 0; i < framData.Count; i++)
            {
                var trackItem = framData[i];
                if (!trackItem.IsDisable)
                {
                    AnimationEvent animEvent = null;
                    int tempOffset = 0;
                    foreach (var item in trackItem.events)
                    {
                        if (item.startIndex <= frameIndex && frameIndex < item.startIndex + item.durationIndex)
                        {
                            tempOffset = frameIndex - item.startIndex;
                            animEvent = item as AnimationEvent;
                            break;
                        }

                    }

                    if (animEvent != null)
                    {
                        // 动画资源总帧数
                        float clipFrameCount = animEvent.animationClip.length * animEvent.animationClip.frameRate;
                        // 计算当前的播放进度
                        float progress = tempOffset / clipFrameCount;
                        // 循环动画的处理
                        if (progress > 1 && animEvent.animationClip.isLooping)
                        {
                            progress -= (int)progress; // 只留小数部分
                        }

                        animator.applyRootMotion = animEvent.applyRootMotion;
                        animEvent.animationClip.SampleAnimation(previewGameObject,
                            progress * animEvent.animationClip.length);
                    }
                }
            }
        }

        public override void TickPreView(int frameIndex)
        {
            GameObject previewGameObject = ActionEditor.Instance.PreviewCharacterObj;
            if (previewGameObject != null)
            {
                previewGameObject.transform.position = GetPositionForRootMotion(frameIndex);
            }

            #endregion
        }
    }
}
